﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Jermaine.Extensions
{
    public static class ListExtension
    {
        /// <summary>
        /// Map Reduce
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="list"></param>
        /// <param name="Map"></param>
        /// <param name="Reduce"></param>
        /// <returns></returns>
        public static IDictionary<TKey, TResult> MapReduce<TKey, TValue, TSource, TResult>(this IEnumerable<TSource> list,
            Func<TSource, IDictionary<TKey, TValue>> Map,
            Func<TKey, IEnumerable<TValue>, TResult> Reduce) {

            var mapped = new Dictionary<TKey, IList<TValue>>();
            foreach (var item in list) {
                foreach (var o in Map(item)) {
                    IList<TValue> mappedList;
                    if (!mapped.TryGetValue(o.Key, out mappedList)) {
                        mappedList = new List<TValue>();
                        mapped.Add(o.Key, mappedList);
                    }
                    mappedList.Add(o.Value);
                }
            }
            var result = new Dictionary<TKey, TResult>();
            foreach (var m in mapped) {
                result.Add(m.Key, Reduce(m.Key, m.Value));
            }
            return result;
        }
    }
}
